﻿# ZenCoding Visual Studio AddIn
# Copyright (C) 2009 Einar Egilsson
# http://tech.einaregilsson.com/2009/11/12/zen-coding-visual-studio-addin/
# 
# Portions of this program (the ZenCoding Python library) were taken from
# the ZenCoding project (http://code.google.com/p/zen-coding/)
# 
# Those parts are copyright (C) 2009 Sergey Chikuyonok (http://chikuyonok.ru)
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
# 
# $Id: snippetscontrol.py 333 2009-12-02 08:02:43Z einar@einaregilsson.com $ 

import zenvs.references, zenvs.addin
from zenvs.settings import load_custom_settings, save_custom_settings
from zenvs.editsnippet import EditSnippet
from ZenCoding.VisualStudio import ZenCodingAddIn
from ZenCoding.VisualStudio.GUI import SnippetsControlBase
from EnvDTE import IDTToolsOptionsPage
from System.Windows.Forms import *

HTML,CSS,COMMON,XSL,SNIPPETS,ABBREVIATIONS = 'html','css','common','xsl','snippets','abbreviations'

class SnippetsControl(SnippetsControlBase, IDTToolsOptionsPage):
	
	def __new__(cls):
		self = SnippetsControlBase.__new__(cls)
		self.btnNew.Click += self.new_snippet
		self.btnDelete.Click += self.delete_snippet
		self.btnEdit.Click += self.edit_snippet
		self.lstSnippets.DoubleClick += self.edit_snippet
		self.lstSnippets.KeyDown += self.snippets_key_down
		self.lstSnippets.ItemSelectionChanged += self.set_enabled
		self.dte = None
		return self
		
	def OnOK(self):
		custom = self.get_current_settings()
		save_custom_settings(custom)
		
		if ZenCodingAddIn.ConnectedInstance:
			ZenCodingAddIn.ConnectedInstance.UpdateSettings()
 		
		#VS2010 beta chokes on this, so we use the singleton hack above instaed
		#try:
		#	self.dte.AddIns.Item(zenvs.addin.PROGID).Object.UpdateSettings()
		#except:
		#	pass #AddIn not loaded
			
	def get_current_settings(self):
		custom = load_custom_settings()
		custom[COMMON] = {SNIPPETS:{},ABBREVIATIONS:{}}
		custom[HTML] = {'extends':COMMON,SNIPPETS:{},ABBREVIATIONS:{}}
		custom[CSS] = {'extends':COMMON,SNIPPETS:{}}
		custom[XSL] = {'extends':','.join((COMMON,HTML)),ABBREVIATIONS:{}}
		for item in self.lstSnippets.Items:
			cat,abbr,text = item.SubItems[0].Text,item.SubItems[1].Text,str(item.Tag)
			custom[cat][SNIPPETS][abbr] = text
			#Don't know the difference for snippets vs abbreviations, snippets seems to work better for custom junk
			#if cat == CSS:
			#	custom[CSS][SNIPPETS][abbr] = text
			#elif cat == XSL:
			#	custom[XSL][ABBREVIATIONS][abbr] = text
			#else:
			#	if '${' in text:
			#		custom[cat][SNIPPETS][abbr] = text
			#	else:
			#		custom[cat][ABBREVIATIONS][abbr] = text
		return custom					
		
	def OnCancel(self):
		pass
		
	def GetProperties(self, props):
		pass
		
	def OnAfterCreated(self, dte):
		self.dte = dte
		self.lstSnippets.Items.Clear()
		custom = load_custom_settings()
		for type in (HTML,CSS,XSL,COMMON):
			if not type in custom:
				continue
			dict = custom[type]
			for subtype in (SNIPPETS,ABBREVIATIONS):
				if subtype in dict:
					for trigger in dict[subtype]:
						item = ListViewItem((type, trigger, dict[subtype][trigger]))
						self.escape_item(item)
						self.lstSnippets.Items.Add(item)
		self.set_enabled()
	
	def new_snippet(self, *args):
		form = EditSnippet(settings=self.get_current_settings())
		if form.ShowDialog() != DialogResult.OK:
			return
		item = ListViewItem((form.Category, form.Abbreviation, form.ExpandedText))
		self.escape_item(item)
		self.lstSnippets.Items.Add(item)
		
	def delete_snippet(self, *args):
		if not self.snippet_is_selected():
			return
		self.lstSnippets.Items.RemoveAt(self.lstSnippets.SelectedIndices[0]);
 
	def edit_snippet(self, *args):
		if not self.snippet_is_selected():
			return
		item = self.lstSnippets.SelectedItems[0]
		form = EditSnippet(item.Text, item.SubItems[1].Text, item.Tag, self.get_current_settings())
		if form.ShowDialog() != DialogResult.OK:
			return
			
		item.Text = form.Category;
		item.SubItems[1].Text = form.Abbreviation
		item.SubItems[2].Text = form.ExpandedText
		self.escape_item(item)
	
	def escape_item(self, item):
		item.Tag = item.SubItems[2].Text
		item.SubItems[2].Text = item.SubItems[2].Text.Replace("\n", "\\n").Replace("\r", "\\r").Replace("\t", "\\t");

	def snippet_is_selected(self):
		return self.lstSnippets.SelectedItems.Count > 0	

	def set_enabled(self, *args):
		self.btnEdit.Enabled = self.snippet_is_selected()
		self.btnDelete.Enabled = self.snippet_is_selected()

	def snippets_key_down(self, sender, args):
		if args.KeyCode == Keys.Delete:
			self.delete_snippet()
